/* Copyright (c) 2009 Christopher Humphries, Maxime Simon
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package macro;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Humphries Christopher - Simon Maxime
 * 
 */
public class Originator {

    private List<Action> m_actions = new ArrayList<Action>();

    private String m_commandName;
    private int m_start;
    private int m_end;
    private char m_value;

    private int m_currentActionIndex = 0;

    /**
     * 
     */
    public void storeAction() {
	m_actions.add(new Action(m_commandName, m_start, m_end, m_value));
	System.out.println(m_commandName + "," + m_start + "," + m_end + ","
		+ m_value);
    }

    /**
     * @return
     */
    public int start() {
	return m_start;
    }

    /**
     * @param start
     */
    public void setStart(int start) {
	m_start = start;
    }

    /**
     * @return
     */
    public int end() {
	return m_end;
    }

    /**
     * @param end
     */
    public void setEnd(int end) {
	m_end = end;
    }

    /**
     * @return
     */
    public char value() {
	return m_value;
    }

    /**
     * @param value
     */
    public void setValue(char value) {
	m_value = value;
    }

    /**
     * @return
     */
    public String commandName() {
	return m_commandName;
    }

    /**
     * @param command
     */
    public void setCommandName(String command) {
	m_commandName = command;
    }

    /**
     * @return
     */
    public Object saveToMacro() {
	Macro macro = new Macro(m_actions);
	m_actions = new ArrayList<Action>();

	return macro;
    }

    /**
     * @param m
     */
    public void restoreFromMacro(Object m) {
	if (m instanceof Macro) {
	    Macro macro = (Macro) m;
	    m_actions = macro.actions();
	    m_currentActionIndex = 0;
	}
    }

    /**
     * 
     */
    public void discardMacro() {
	m_actions.clear();
    }

    /**
     * @return
     */
    public boolean nextAction() {
	boolean result = false;

	if (m_currentActionIndex < m_actions.size()) {
	    Action action = m_actions.get(m_currentActionIndex);

	    m_commandName = action.commandName();
	    m_start = action.start();
	    m_end = action.end();
	    m_value = action.value();

	    m_currentActionIndex++;
	    result = true;
	}

	return result;
    }

    private class Action {

	private int m_start, m_end;
	private char m_value;

	/**
	 * @param commandName
	 * @param start
	 * @param end
	 * @param value
	 */
	public Action(String commandName, int start, int end, char value) {
	    m_commandName = commandName;
	    m_start = start;
	    m_end = end;
	    m_value = value;
	}

	/**
	 * @return
	 */
	public char value() {
	    return m_value;
	}

	/**
	 * @return
	 */
	public String commandName() {
	    return m_commandName;
	}

	/**
	 * @return
	 */
	public int start() {
	    return m_start;
	}

	/**
	 * @return
	 */
	public int end() {
	    return m_end;
	}
    }

    private static class Macro {

	private List<Action> m_actions = new ArrayList<Action>();

	/**
	 * @return
	 */
	public List<Action> actions() {
	    return m_actions;
	}

	/**
	 * @param actions
	 */
	public Macro(List<Action> actions) {
	    m_actions = actions;
	}
    }
}
